package com.lqg.bookLibrary.controller;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.lqg.bookLibrary.common.core.domain.JsonResult;
import com.lqg.bookLibrary.pojo.AvgScore;
import com.lqg.bookLibrary.pojo.Books;
import com.lqg.bookLibrary.pojo.Type;
import com.lqg.bookLibrary.service.IAvgScoreService;
import com.lqg.bookLibrary.service.IBooksService;
import com.lqg.bookLibrary.service.ITypeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.parameters.P;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/book")
@CrossOrigin
public class SearchController {

    @Autowired
    private IBooksService booksService;

    @Autowired
    private ITypeService typeService;

    @Autowired
    private IAvgScoreService avgScoreService;

    @GetMapping("/search/{val}")
    public JsonResult search(@PathVariable String val) {

        String[] s = val.split(" ");
        List<Type> typeList = new ArrayList<>();
        List<Books> booksList = new ArrayList<>();

        for (String s1 : s) {
            List<Type> list = typeService.lambdaQuery().like(Type::getTypeName, s1).list();
            if (list.size() != 0) {
                typeList.addAll(list);
            }
        }

        if (typeList.size() == 0) {
            for (String s1 : s) {
                List<Books> list = booksService.lambdaQuery()
                        .like(Books::getTitle, s1)
                        .or()
                        .like(Books::getAuthor, s1)
                        .list();
                if (list.size() != 0) {
                    booksList.addAll(list);
                }
            }
        }else {
            for (String s1 : s) {
                List<Books> list = booksService.lambdaQuery()
                        .like(Books::getTitle, s1)
                        .or()
                        .like(Books::getAuthor, s1)
                        .or()
                        .in(Books::getTypeId, typeList.stream().map(x -> x.getTypeId()).collect(Collectors.toList()))
                        .list();
                if (list.size() != 0) {
                    booksList.addAll(list);
                }
            }
        }

        if (booksList.size() == 0) {
            return JsonResult.success(new ArrayList<>());
        }

        List<AvgScore> avgScoreList = avgScoreService.lambdaQuery()
                .in(AvgScore::getBookId,
                        booksList.stream().map(Books::getBookId).collect(Collectors.toList())
                ).list();

        List<JSONObject> jsonObjectList = booksList.stream()
                .map(x -> {
                    JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(x));
                    jsonObject.put("score",
                            avgScoreList.stream().filter(y -> Objects.equals(y.getBookId(), x.getBookId())).findFirst().get().getAvgScore()
                    );
                    return jsonObject;
                }).collect(Collectors.toList());

        List<JSONObject> result = jsonObjectList.stream().sorted(
                Comparator.comparingDouble(x -> Double.parseDouble(x.get("score").toString()))
                ).collect(Collectors.toList());

        Collections.reverse(result);

        return JsonResult.success(result);
    }

}
